/**
 *
 * Copyright (c) 2009-2012 Envision Mobile Ltd. All rights reserved.
 *
 * Other software and company names mentioned herein or used for developing
 * and/or running the Envision Mobile Ltd's software may be trademarks or trade
 * names of their respective owners.
 *
 * Everything in the source code herein is owned by Envision Mobile Ltd.
 * The recipient of this source code hereby acknowledges and agrees that such
 * information is proprietary to Envision Mobile Ltd. and shall not be used, 
 * disclosed, duplicated, and/or reversed engineered except in accordance
 * with the express written authorization of Envision Mobile Ltd.
 *
 * Module: DrugExtraDTO.java
 * Project: ReyOfLight
 *
 * Description:
 *
 *
 * Developer:   10107896
 * Date:        2012-08-16
 * Version:		1.0
 *
 *
 */
package DTO;

import java.io.ByteArrayInputStream;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.util.ArrayList;
import java.util.Locale;

import org.Consts;
import org.Globals;
import org.Utility;
import org.sqlStatements;

import CustomUI.DrawingSurface;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.util.Log;

/**
 * @author 10107896
 * 
 */
public class DrawingDTO extends BaseDTO {

	SQLiteDatabase db = Globals.sqlDB;
	public int did;
	public String name;
	public int lastState = 0;
	public Bitmap image;

	ArrayList<LayerDTO> layer;

	/*
	 * public DrawingDTO(int id, SQLiteDatabase db) { did = id;
	 * 
	 * Cursor c = null; c = db.rawQuery("Select * from ? where " +
	 * sqlStatements.DID + " = ?", new String[] { sqlStatements.DRAWINGS, did +
	 * "" });
	 * 
	 * if (c != null) { if (c.moveToFirst()) { name = c.getString(0); lastState
	 * = c.getInt(1); byte[] pic = (c.getBlob(3)); ByteArrayInputStream
	 * imageStream = new ByteArrayInputStream(pic); image =
	 * BitmapFactory.decodeStream(imageStream);
	 * 
	 * } else { Log.d("",
	 * "== something happened, could not extract from database"); } if (c !=
	 * null) { c.close(); } } else { Log.d("", "== c was null"); } }
	 */

	public ArrayList<LayerDTO> getLayer() {
		return layer;
	}

	public LayerDTO getLayer(int id) {
		for (LayerDTO l : layer) {
			if (l.lid == id)
				return l;
		}
		return null;
	}

	public LayerDTO getLayerWithZ(int i) {
		for (LayerDTO l : layer) {
			if (l.zindex == i)
				return l;
		}
		return null;
	}

	public void setLayer(ArrayList<LayerDTO> layer) {
		this.layer = layer;
	}

	public DrawingDTO(SQLiteDatabase db) {
		this.db = db;
		lastState = 0;
		name = "Untitled";
		ContentValues values = new ContentValues();
		values.put(sqlStatements.LASTSTATE, lastState);
		values.put(sqlStatements.NAME, name);
		did = (int) db.insert(sqlStatements.DRAWINGS, null, values);
		layer = new ArrayList<LayerDTO>();
		// layer.add(new LayerDTO(did, lastState, db));
		return;
	}

	public DrawingDTO(SQLiteDatabase sqlDB, int id) {
		this.db = sqlDB;
		did = id;
		Cursor c = null;
		c = db.query(sqlStatements.DRAWINGS,
				new String[] { sqlStatements.LASTSTATE }, sqlStatements.DID
						+ "=?", new String[] { id + "" }, null, null, null);

		if (c != null) {
			if (c.moveToFirst()) {
				lastState = c.getInt(0);
				layer = LayerDTO.getLayers(did, sqlDB);
			}
		}

	}

	public DrawingDTO() {
		// TODO Auto-generated constructor stub
	}

	public int update() {
		ContentValues values = new ContentValues();
		values.put(sqlStatements.LASTSTATE, lastState);
		return db.update(sqlStatements.DRAWINGS, values, sqlStatements.DID
				+ "=?", new String[] { did + "" });
	}

	/*
	 * public boolean insertIntoDatabase(SQLiteDatabase db) { this.db = db; try
	 * { ContentValues values = new ContentValues(); byte[] img =
	 * Utility.bitmaptoByteArray(image); values.put(Consts.COLUMN_IMAGE, img);
	 * 
	 * int id = (int) db.insert(Consts.TABLE_OBJECT, null, values);
	 * 
	 * if (id > 0) { intUuid = id; Log.d("",
	 * "== was successfully inserted in db, Object"); } else Log.d("",
	 * "== unsuccessful in inserting in db, Object");
	 * 
	 * return id > 0; } catch (Exception e) { e.printStackTrace();
	 * 
	 * Log.d("", "== unsucessful in inserting in db, Object, exception"); }
	 * return false; }
	 */
	/*
	 * public static ArrayList<DrawingDTO> getObjectsInDatabase(SQLiteDatabase
	 * db) {
	 * 
	 * ArrayList<DrawingDTO> objects = new ArrayList<DrawingDTO>();
	 * 
	 * try { // SELECT id FROM drug_extra WHERE drug_id=? //
	 * sqlite3_bind_int(statement, 1, drugUUID) String sql = "SELECT _id FROM "
	 * + Consts.TABLE_OBJECT; Cursor c = db.rawQuery(sql, null);
	 * 
	 * while (c.moveToNext()) {
	 * 
	 * int primaryKey = c.getInt(0); DrawingDTO obj = new DrawingDTO(primaryKey,
	 * db); objects.add(obj); }
	 * 
	 * if (c != null) { c.close(); }
	 * 
	 * } catch (Exception e) { e.printStackTrace(); Log.d("",
	 * "== something went wrong, drugExtra, getDrugExtraDB"); }
	 * 
	 * return objects; }
	 */

	/*
	 * public void delete(SQLiteDatabase db) { // ArrayList<DrawingPlaneDTO> //
	 * drawingPlanes=DrawingPlaneDTO.getDrawingPlaneForObjectInDatabase(intUuid,
	 * // db);
	 * 
	 * DrawingPlaneDTO.deleteDrawingPlanesForObjectInDatabase(intUuid, db);
	 * deleteObject(intUuid, db);
	 * 
	 * }
	 */

	public int addLayer(DrawingSurface drawingSurface, int currentInstruct) {
		LayerDTO l = new LayerDTO(did, currentInstruct, db, drawingSurface, layer.size());
		layer.add(l);
		// drawingSurface.addLayerView(l.LV);
		return l.lid;
	}

	private void deleteObject(int id, SQLiteDatabase db) {
		try {
			boolean state = db.delete(Consts.TABLE_OBJECT, "_id=?",
					new String[] { id + "" }) > 0;

			if (state)
				Log.d("", "== successfully deleted, dose");
			else
				Log.d("", "== problem deleting, dose");
		} catch (SQLException e) {
			Log.e("Database Error: ", e.toString());
			e.printStackTrace();
		}

	}

	public int getFirstLayerID() {
		return ((LayerDTO) layer.get(0)).lid;

	}

	public void draw(DrawingSurface drawingSurface) {
		for (LayerDTO l : layer) {
			drawingSurface.addLayerView(l.LV);
			int x = l.draw(lastState);
			if (x == -1) {
				drawingSurface.removeLayerView(l.LV);
			}
		}
	}

	public void drawAll(DrawingSurface drawingSurface) {
		for (LayerDTO l : layer) {
			drawingSurface.addLayerView(l.LV);
			l.drawAll();
		}

	}

	/*
	 * public void draw(DrawingSurface drawingSurface, int currentLayer){
	 * 
	 * }
	 */
	public void addToLayer(int currentLayer, DrawingCmdDTO dC) {
		// db.execSQL(sql);
		DrawingCmdDTO d = new DrawingCmdDTO();
		for (LayerDTO l : layer) {
			d.lid = l.lid;
			d.instructNum = dC.instructNum;
			if (l.lid == currentLayer) {
				l.addDC(dC);
			} else {
				l.removeCMDAndAfter(d);
			}
		}

	}

	public void addToLayer(int currentLayer, DrawingCmdDTO dC, boolean redraw) {
		DrawingCmdDTO d = new DrawingCmdDTO();
		for (LayerDTO l : layer) {
			d.lid = l.lid;
			d.instructNum = dC.instructNum;
			if (l.lid == currentLayer) {
				l.addDC(dC,redraw);
			} else {
				l.removeCMDAndAfter(d);
			}
		}
		
	}

	public NextStep Undo(int currentInstruct) {
		int i = -1;
		NextStep ns1;
		NextStep ns2 = null;
		for (LayerDTO l : layer) {
			ns1 = l.Undo(currentInstruct);
			if (ns1.getIsThis()) {
				ns2 = ns1;
			}
		}
		return ns2;
	}

	public int getLastState() {
		return lastState;
	}

	public void setLastState(int lastState) {
		this.lastState = lastState;
	}

	public NextStep Redo(int currentInstruct) {
		int i = -1;
		NextStep ns1;
		NextStep ns2 = null;
		for (LayerDTO l : layer) {
			ns1 = l.Redo(currentInstruct);
			if (ns1.getIsThis()) {
				ns2 = ns1;
			}
		}
		return ns2;
	}

	public static ArrayList<Integer> getAllDrawingsID() {

		ArrayList<Integer> result = new ArrayList<Integer>();

		try {
			Cursor c = null;
			c = Globals.sqlDB.query(sqlStatements.DRAWINGS,
					new String[] { sqlStatements.DID }, "", new String[] {},
					"", "", sqlStatements.DID);

			if (c != null) {
				while (c.moveToNext()) {
					int x = c.getInt(0);
					result.add(x);
				}
			} else {
				Log.d("",
						"== something happened, could not extract from database");
			}
			if (c != null) {
				c.close();
			} else {
				Log.d("", "== c was null");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return result;
	}

	public static ArrayList<DrawingDTO> getAllDrawings(Boolean withImage) {

		ArrayList<DrawingDTO> result = new ArrayList<DrawingDTO>();

		try {
			Cursor c = null;
			if (withImage) {
				c = Globals.sqlDB.query(sqlStatements.DRAWINGS, new String[] {
						sqlStatements.DID, sqlStatements.NAME,
						sqlStatements.LASTSTATE, sqlStatements.IMAGE }, "",
						new String[] {}, "", "", sqlStatements.DID);
			} else {
				c = Globals.sqlDB.query(sqlStatements.DRAWINGS, new String[] {
						sqlStatements.DID, sqlStatements.NAME,
						sqlStatements.LASTSTATE }, "", new String[] {}, "", "",
						sqlStatements.DID);
			}

			if (c != null) {
				while (c.moveToNext()) {
					DrawingDTO d = new DrawingDTO();
					d.setDid(c.getInt(0));
					d.setName(c.getString(1));
					d.setLastState(c.getInt(2));
					if (withImage) {
						byte[] pic = (c.getBlob(3));
						ByteArrayInputStream imageStream = new ByteArrayInputStream(
								pic);
						d.setImage(BitmapFactory.decodeStream(imageStream));
					}
					result.add(d);
				}
			} else {
				Log.d("",
						"== something happened, could not extract from database");
			}
			if (c != null) {
				c.close();
			} else {
				Log.d("", "== c was null");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return result;
	}

	public int getDid() {
		return did;
	}

	public void setDid(int did) {
		this.did = did;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Bitmap getImage() {
		return image;
	}

	public void setImage(Bitmap image) {
		this.image = image;
	}

	public static Bitmap getCurrentDrawing(int i) {

/*		try {
			Cursor c = null;
			c = Globals.sqlDB.query(sqlStatements.DRAWCMD,
					new String[] { sqlStatements.IMAGE }, sqlStatements.DID
							+ "=?", new String[] { i + "" }, "", "", "");
			
			c=Globals.sqlDB.rawQuery("Select " + sqlStatements.IMAGE +
					" From " + sqlStatements.DRAWCMD + " DC, " +sqlStatements.LAYERS + " L"
					+ "on DC.lid=L.lid Where l.did=" + i + " Order By L.zindex", selectionArgs)

			if (c != null) {
				if (c.moveToFirst()) {
					byte[] pic = (c.getBlob(2));
					ByteArrayInputStream imageStream = new ByteArrayInputStream(
							pic);
					return (BitmapFactory.decodeStream(imageStream));
				}
			} else {
				Log.d("",
						"== something happened, could not extract from database");
			}
			if (c != null) {
				c.close();
			} else {
				Log.d("", "== c was null");
			}
		} catch (Exception e) {
			e.printStackTrace();
			Log.d("", "== something went wrong");
		}*/

		String sql = "Select d." + sqlStatements.LID + ", max("
				+ sqlStatements.INSTRUCT_NUM + ")," + sqlStatements.IMAGE
				+ " from " + sqlStatements.DRAWCMD + " d Join " + sqlStatements.LAYERS + " l on  d." + sqlStatements.LID + " =l." 
				+ sqlStatements.LID +  " where "
				+ sqlStatements.INSTRUCT_NUM + "<=(select "
				+ sqlStatements.LASTSTATE + " from " + sqlStatements.DRAWINGS
				+ " where " + sqlStatements.DID + "=" + i + " ) " + "and "
				+ "(select count(" + sqlStatements.LID + ") from "
				+ sqlStatements.LAYERS + " where " + sqlStatements.DID + "="
				+ i + " and d." + sqlStatements.LID + "=" + sqlStatements.LID
				+ ")>0 " + "group by d." + sqlStatements.LID + " Order By " + sqlStatements.ZINDEX;

		ArrayList<Bitmap> bitmaps = new ArrayList<Bitmap>();
		try {
			Cursor c = null;
			c = Globals.sqlDB.rawQuery(sql, null);

			if (c != null) {
				while (c.moveToNext()) {
					byte[] pic = (c.getBlob(2));
					ByteArrayInputStream imageStream = new ByteArrayInputStream(
							pic);
					bitmaps.add(BitmapFactory.decodeStream(imageStream));
				}
			} else {
				Log.d("",
						"== something happened, could not extract from database");
			}
			if (c != null) {
				c.close();
			} else {
				Log.d("", "== c was null");
			}
		} catch (Exception e) {
			e.printStackTrace();
			Log.d("", "== something went wrong");
		}

		Bitmap finalImage;
		if (bitmaps.size() > 0)
			finalImage = Bitmap.createBitmap(bitmaps.get(0).getWidth(), bitmaps
					.get(0).getHeight(), Bitmap.Config.ARGB_8888);
		else
			finalImage = Bitmap.createBitmap(500, 500, Bitmap.Config.ARGB_8888);

		Canvas canvas = new Canvas(finalImage);

		for (Bitmap b : bitmaps) {
			canvas.drawBitmap(b, 0, 0, new Paint());
		}

		DrawingDTO.update(i, finalImage);

		return finalImage;

	}

	private static void update(int i, Bitmap finalImage) {
		Bitmap bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.RGB_565);

		byte[] img;
		if (finalImage == null)
			img = Utility.bitmaptoByteArray(bitmap);
		else
			img = Utility.bitmaptoByteArray(finalImage);

		ContentValues values = new ContentValues();
		values.put(sqlStatements.IMAGE, img);

		Globals.sqlDB.update(sqlStatements.DRAWINGS, values, sqlStatements.DID
				+ "=?", new String[] { i + "" });

	}

	public static void changeName(int id, String name) {
		ContentValues values = new ContentValues();
		values.put(sqlStatements.NAME, name);
		Globals.sqlDB.update(sqlStatements.DRAWINGS, values, sqlStatements.DID
				+ "=?", new String[] { id + "" });

	}

	public static void delete(int did) {
		Globals.sqlDB.delete(sqlStatements.DRAWINGS, sqlStatements.DID + "=?",
				new String[] { did + "" });

	}

}
